#pragma once

#include <Windows.h>
#include <hidsdi.h>
// wil should be included after system API headers
#include "wil/resource.h"

#include <memory>

namespace TLAC::Input::RawInputDetails
{
	struct free_deleter {
		template <typename T>
		void operator()(T* p) const {
			std::free(const_cast<std::remove_const_t<T>*>(p));
		}
	};

	// A unique_ptr that manages memory allocated by std::malloc().
	template <typename T>
	using unique_malloc_ptr = std::unique_ptr<T, free_deleter>;

	// This type should be used to hold output from HidD_GetPreparsedData, since it must be freed with HidD_FreePreparsedData.
	using unique_hidp_preparsed_data_from_get = wil::unique_any<PHIDP_PREPARSED_DATA, decltype(&HidD_FreePreparsedData), HidD_FreePreparsedData>;

	// This type should be used when the caller needs to allocate memory with malloc().
	using unique_hidp_preparsed_data = unique_malloc_ptr<std::remove_pointer<PHIDP_PREPARSED_DATA>::type>;

	inline void __stdcall CloseOverlapped(OVERLAPPED* ov) {
		if (ov->hEvent != NULL) {
			CloseHandle(ov->hEvent);
			ov->hEvent = NULL;
		}
	}

	using unique_overlapped = wil::unique_struct<OVERLAPPED, decltype(CloseOverlapped), CloseOverlapped>;
}